import 'package:flutter/cupertino.dart';
import 'package:x3_base_core/x3_base_core.dart';

/// 单个保存表单方法
typedef RequestSaveData = Function(BaseHttpRequestModel request, Map<String, dynamic> data, {bool notShowLoading});
typedef RequestChanged = Function(BaseHttpRequestModel request, dynamic data);

/// 表单共享数据层
class BaseRequestFormProvider {
  static const double maxLabelWidth = 122;

  /// label 宽度
  double labelWidth;

  /// 入参数据
  List<BaseHttpRequestModel> requests;

  /// 元数据
  Map<String, dynamic> dataSource;

  BaseRequestFormProvider({@required List<BaseHttpRequestModel> requests, Map<String, dynamic> dataSource}) : assert(requests != null) {
    this.dataSource = dataSource ?? {};

    /// 过滤隐藏的表单
    this.requests = BaseFormTransformUtil.getShowRequestModels(requests);

    /// 过滤空格
    this.requests.forEach((element) {
      assert(element.fieldName != null);
      assert(element.name != null);
      element.name = element.name.replaceAll(new RegExp(r" \s +"), "");
    });
  }

  /// 工厂模式
  factory BaseRequestFormProvider.formJson({@required List<Map<String, dynamic>> requests, Map<String, dynamic> dataSource}) {
    List<BaseHttpRequestModel> _requests = requests.map((e) => BaseHttpRequestModel.fromJson(e)).toList();
    Map<String, dynamic> _dataSource = dataSource ?? {};
    return BaseRequestFormProvider(requests: _requests, dataSource: _dataSource);
  }

  /// 设置数据
  void setDataSource(BaseHttpRequestModel request, dynamic value) {
    dataSource.addAll({request.fieldName: value});
    this.emitChange(request);
  }

  /// 获取值
  dynamic getDataSource(BaseHttpRequestModel request) {
    return this.dataSource[request.fieldName];
  }

  /// 通过字符串获取 data
  dynamic fieldNameToDataSource(String fieldName) {
    if (this.dataSource.containsKey(fieldName)) {
      return this.dataSource[fieldName];
    }
    return null;
  }

  /// 获取 对象或集合的 key
  dynamic getDataKey(BaseHttpRequestModel request) {
    var value = this.getDataSource(request);

    /// 如果是集合
    if (value is List) {
      return value.map((e) {
        if (value is Map) return e['key'];
        if (value is BaseKeyValueModel) return e.key;
        return e;
      }).toList();
    }

    /// 单个的情况
    if (value is Map) return value['key'];

    if (value is BaseKeyValueModel) return value.key;

    return value;
  }

  /// 拼上 fieldName
  Map<String, dynamic> getDataMapKey(BaseHttpRequestModel request) {
    var value = getDataKey(request);
    return {request.fieldName: value};
  }

  /// 获取搜索 data key
  Map<String, dynamic> getAllDataMapKey() {
    Map<String, dynamic> params = {};
    for (BaseHttpRequestModel request in this.requests) {
      params.addAll(getDataMapKey(request));
    }
    return params;
  }

  /// 获取键值对
  Map<String, dynamic> getMapDataSource(BaseHttpRequestModel request) {
    return {request.fieldName: getDataSource(request)};
  }

  /// 判断是否可读
  bool isReadonly(BaseHttpRequestModel request) {
    return request.accessMode == BaseHttpAccessModelEnum.WebReadOnly;
  }

  /// 根据 fieldName 找数据
  dynamic findData(BaseHttpRequestModel request) {
    var data = this.dataSource.containsKey(request.fieldName) ? this.dataSource[request.fieldName] : null;
    if (data is List || data is String) {
      data = data.length == 0 ? null : data;
    }
    if (data is Map) {
      data = data.keys.length == 0 ? null : data;
    }
    return data;
  }

  /// 验证器
  bool validationDataSource({bool isShowToast = true, String head = ""}) {
    String _errorText;
    for (BaseHttpRequestModel item in this.requests) {
      var currentData = this.dataSource[item.fieldName];
      bool _isEmpty = currentData == null || currentData.toString().trim().isEmpty;

      /// 是否必填
      if (item.required == true) {
        if (_isEmpty) {
          _errorText = '$head${item.name}不能为空！';
          break;
        }
      }

      /// 正则校验
      if (!_isEmpty) {
        if (item.inputRegex != null && item.inputRegex.trim().isNotEmpty) {
          RegExp reg = RegExp("${item.inputRegex}");
          bool success = reg.hasMatch(currentData.toString());
          if (!success) {
            _errorText = '$head${item.name}格式错误！';
            break;
          }
        }
      }
    }
    bool isSave = _errorText != null ? false : true;
    if (isSave == false && isShowToast) BaseUtils.showToast(_errorText);
    return isSave;
  }

  /// 设置label 宽度
  void setLabelWidth({double width = BaseRequestFormProvider.maxLabelWidth}) {
    this.requests.forEach((element) {
      if (this.labelWidth != null) {
        element.labelWidth = this.labelWidth;
      } else {
        element.labelWidth = width;
      }
    });
  }

  /// 针对于 输入框 焦点监听
  Function(bool hasFocus, BaseHttpRequestModel request) _focusNodeListener;

  void focusNodeListener(Function(bool hasFocus, BaseHttpRequestModel request) listener) {
    _focusNodeListener = listener;
  }

  /// 发送 监听
  void emitFocusNode(bool hasFocus, BaseHttpRequestModel request) {
    if (_focusNodeListener != null) _focusNodeListener(hasFocus, request);
  }

  /// 获取事件改变值监听
  RequestChanged _changeListener;

  void onChangeListener(RequestChanged listener) {
    _changeListener = listener;
  }

  /// 发送改变监听
  void emitChange(BaseHttpRequestModel request) {
    if (_changeListener != null) {
      _changeListener(request, this.getDataSource(request));
    }
  }

  static BaseRequestFormProvider of(BuildContext context, {bool listen = true}) {
    return Provider.of<BaseRequestFormProvider>(context, listen: listen);
  }
}
